home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 425_01 / lzpipe / bits.c < prev    next >
Text File  |  1994-03-13  |  3KB  |  120 lines

  1. #include <stdio.h>
  2. #include "modern.h"
  3. #include "stdinc.h"
  4. #include "zalloc.h"
  5. #include "zipdefs.h"
  6. #include "zipguts.h"
  7. #include "lzpipe.h"
  8.  
  9. static unsigned bitbuff;
  10. static int boffset;
  11.  
  12. #ifdef DEBUG
  13. ulg bits_sent;   /* bit length of the compressed data */
  14. #endif
  15.  
  16. #ifdef __TURBOC__
  17.     #include <dos.h>
  18.         #pragma warn -rvl
  19. #endif
  20. unsigned bi_reverse(code, len) /* Reverse the first len bits of a code. */
  21. unsigned code; /* the value to invert */
  22. int len;       /* its bit length: 1 =< len =< 15 */
  23. {
  24. #ifdef __TURBOC__
  25.    _DX = code;  /* inline assembly ha-ha! */
  26.    _CX = len;
  27.    __emit__(/* all arguments must be words to avoid confusion */
  28.    0xC031,  /* xor ax,ax */
  29.    0xEAD1,  /* shr dx,1  */
  30.    0xD0D1,  /* rcl ax,1  */
  31.    0xFAE2); /* loop $-4  */
  32. #else
  33.    register unsigned res = 0;
  34.    do res = (res << 1) | (code & 1), code>>=1; while (--len);
  35.    return res;
  36. #endif
  37. }
  38. #ifdef __TURBOC__
  39.         #pragma warn .rvl
  40. #endif
  41.  
  42. void bi_init() /* Initialize the bit string routines. */
  43. {
  44.    bitbuff = 0;
  45.    boffset = 0;
  46. #ifdef DEBUG
  47.    bits_sent = 0L;
  48. #endif
  49. }
  50.  
  51. int send_bits(value, length) /* Send a value on a given number of bits. */
  52. unsigned value; /* value to send */
  53. int length;     /* number of bits: length =< 16 */
  54. {
  55. #ifdef DEBUG
  56.    Tracevv((stderr," l %2d v %4x ", length, value));
  57.    Assert(length > 0 && length <= 15, "invalid length");
  58.    Assert(boffset < 8, "bad offset");
  59.    bits_sent += (ulg)length;
  60. #endif
  61.    bitbuff |= value << boffset;
  62.    if ((boffset += length) >= 8) {
  63.       if (putbyte(bitbuff) == EOF) return -1;
  64.       value >>= length - (boffset -= 8);
  65.       if (boffset >= 8) {
  66.          boffset -= 8;
  67.          if (putbyte(value) == EOF) return -1;
  68.          value >>= 8;
  69.       }
  70.       bitbuff = value;
  71.    }
  72.    return 0;
  73. }
  74.  
  75. /* Write out any remaining bits in an incomplete byte. */
  76. int bi_windup()
  77. {
  78.    Assert(boffset < 8, "bad offset");
  79.    if (boffset) {
  80.       if (putbyte(bitbuff) == EOF) return -1;
  81.       boffset = 0;
  82.       bitbuff = 0;
  83. #ifdef DEBUG
  84.       bits_sent = (bits_sent+7) & ~7;
  85. #endif
  86.    }
  87.    return 0;
  88. }
  89.  
  90. int bi_putsh(x)
  91. unsigned short x;
  92. {
  93.    return (putbyte(x&255)==EOF || putbyte((x>>8)&255)==EOF) ? -1 : 0;
  94. }
  95.  
  96. /* Copy a stored block to the zip file, storing first the length and its
  97.    one's complement if requested. */
  98. int copy_block(buf, len, header)
  99. char far *buf; /* the input data */
  100. unsigned len;  /* its length */
  101. int header;    /* true if block header must be written */
  102. {
  103.    /* align on byte boundary */
  104.    if (bi_windup() != 0) return -1;
  105.  
  106.    if (header) {
  107.       if (bi_putsh(len) != 0 || bi_putsh(~len) != 0) return -1;
  108. #ifdef DEBUG
  109.       bits_sent += 2*16;
  110. #endif
  111.    }
  112.    while (len--) {
  113.       if (putbyte(*buf++) == EOF) return -1;
  114.    }
  115. #ifdef DEBUG
  116.    bits_sent += (ulg)len<<3;
  117. #endif
  118.    return 0;
  119. }
  120.